<script lang="ts" setup name="SidebarItem">
// import SidebarItem from './sub.vue'
import { resolveRoutePath } from '@g/utils'
import useSettingsStore from '@g/store/modules/settings'
import type { Menu } from '@g/types/global'
import { InjectionI18nTitle } from '@/global/utils/injection-keys'
import router from '@/global/router'

const props = defineProps({
  item: {
    type: Object as () => Menu.recordRaw as any,
    required: true
  },
  basePath: {
    type: String,
    default: ''
  },
  link: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['handLink'])
const settingsStore = useSettingsStore()

const generateI18nTitle = inject(InjectionI18nTitle) as Function

const isSingleMenu = computed(() => {
  return (props.item.children?.length === 1 && props.item.children[0].path === (props.item as any)?.path)
})
const hasChildren = computed(() => {
  let flag = true
  if (props.item.children) {
    if (props.item.children.every((item: any) => item.meta?.sidebar === false))
      flag = false
  }
  else {
    flag = false
  }
  return flag
})

function iconName(isActive: boolean, icon?: string, activeIcon?: string) {
  let name
  if ((!isActive && icon) || (isActive && !activeIcon))
    name = icon
  else if (isActive && activeIcon)
    name = activeIcon
  return name
}
function badge(badge?: string | number | boolean | Function) {
  const res = {
    type: '', // text or dot
    value: '',
    visible: false
  }
  if (badge) {
    res.visible = true
    res.value = typeof badge === 'function' ? badge() : badge
    if (typeof res.value === 'boolean') {
      res.type = 'dot'
      if (!res.value)
        res.visible = false
    }
    else if (typeof res.value === 'number') {
      res.type = 'text'
      if (res.value <= 0)
        res.visible = false
    }
    else {
      res.type = 'text'
      if (!res.value)
        res.visible = false
    }
  }
  return res
}

const handLink = () => {
  emit('handLink')
}

const handSingleMenuLink = () => {
  emit('handLink')
  try {
    if (props?.item?.link?.startsWith('http')) {
      window.open(props.item.link)
      return
    }
    router.push({
      path: (props.item as any)?.path
    })
  }
  catch (error) {
    router.push({
      path: (props.item as any)?.path
    })
  }
}

const isHead = computed(() => settingsStore.settings.menu.menuMode === 'head')

const enableIcon = computed(() => settingsStore.settings.menu.showTopMenuIcon)
</script>

<template>
  <div class="sidebar-item">
    <router-link
      v-if="!hasChildren && link"
      v-slot="{ href, navigate, isActive, isExactActive }"
      custom
      :to="resolveRoutePath(basePath, item.path)"
    >
      <a
        :href="item.meta?.link ? item.meta.link : href"
        :class="[
          isActive && 'router-link-active',
          isExactActive && 'router-link-exact-active',
        ]"
        :target="item.meta?.link ? '_blank' : '_self'"
        @click="navigate"
      >
        <el-menu-item
          :title="generateI18nTitle(item.meta?.i18n, item.meta?.title)"
          :index="resolveRoutePath(basePath, item.path || item.meta?.path)"
        >
          <template
            v-if="isHead && link
              && iconName(
                isActive || isExactActive,
                item.meta?.icon,
                item.meta?.activeIcon,
              )
            "
          >
            <IkSvgIcon
              :size="18"
              :name="iconName(isActive || isExactActive, item.meta?.icon, item.meta?.activeIcon) as string"
              class="title-icon"
            />
          </template>
          <span v-else-if="link" class="sub-menu-point"></span>
          <span class="ik-menu-title">{{ generateI18nTitle(item.meta?.i18n, item.meta?.title) }}</span>
          <span
            v-if="badge(item.meta?.badge).visible"
            class="badge"
            :class="{
              'badge-dot': badge(item.meta?.badge).type === 'dot',
              'badge-text': badge(item.meta?.badge).type === 'text',
            }"
          >{{
            badge(item.meta?.badge).type === 'text'
              ? badge(item.meta?.badge).value
              : ''
          }}</span>
        </el-menu-item>
      </a>
    </router-link>
    <template v-else-if="isSingleMenu">
      <el-sub-menu
        :title="generateI18nTitle(item.meta?.i18n, item.meta?.title)"
        :index="settingsStore.settings.app.routeBaseOn !== 'filesystem'
          ? resolveRoutePath(basePath, item.path || item.meta?.path)
          : JSON.stringify(item)
        "
        class="none-body single-menu"
        :class="{ 'is-firstLevel': !item.meta?.isFirstLevel }"
        @click="handSingleMenuLink"
      >
        <template #title>
          <template v-if="item.meta?.isFirstLevel || isHead">
            <IkSvgIcon
              v-if="item.meta?.icon"
              :size="18"
              class="title-icon unactive"
              :name="item.meta.icon"
            />
            <IkSvgIcon
              v-if="item.meta?.activeIcon || item.meta?.icon"
              :size="18"
              class="title-icon active"
              :name="(item.meta.activeIcon || item.meta.icon) as string"
            />
          </template>
          <span v-else class="sub-menu-point"></span>
          <!-- RM: 侧边栏一级导航 -->
          <span class="ik-menu-title">{{ generateI18nTitle(item.meta?.i18n, item.meta?.title) }}</span>
          <span
            v-if="badge(item.meta?.badge).visible"
            class="badge"
            :class="{
              'badge-dot': badge(item.meta?.badge).type === 'dot',
              'badge-text': badge(item.meta?.badge).type === 'text',
            }"
          >{{
            badge(item.meta?.badge).type === 'text'
              ? badge(item.meta?.badge).value
              : ''
          }}</span>
        </template>
      </el-sub-menu>
    </template>
    <template v-else-if="!link">
      <el-menu-item
        :title="generateI18nTitle(item.meta?.i18n, item.meta?.title)"
        :index="resolveRoutePath(basePath, item.path || item.meta?.path)"
        @click="handLink"
      >
        <IkSvgIcon
          v-if="enableIcon"
          :size="18"
          :name="item.meta?.icon"
          class="title-icon"
        />
        <span class="ik-menu-title">{{ generateI18nTitle(item.meta?.i18n, item.meta?.title) }}</span>
        <span
          v-if="badge(item.meta?.badge).visible"
          class="badge"
          :class="{
            'badge-dot': badge(item.meta?.badge).type === 'dot',
            'badge-text': badge(item.meta?.badge).type === 'text',
          }"
        >{{
          badge(item.meta?.badge).type === 'text'
            ? badge(item.meta?.badge).value
            : ''
        }}</span>
      </el-menu-item>
    </template>
    <el-sub-menu
      v-else
      :title="generateI18nTitle(item.meta?.i18n, item.meta?.title)"
      :index="settingsStore.settings.app.routeBaseOn !== 'filesystem'
        ? resolveRoutePath(basePath, item.path || item.meta?.path)
        : JSON.stringify(item)
      "
      popper-class="fa-popup-menu"
      :class="{ 'is-firstLevel': !item.meta?.isFirstLevel }"
    >
      <template #title>
        <template v-if="item.meta?.isFirstLevel || isHead">
          <IkSvgIcon
            v-if="item.meta?.icon"
            :size="18"
            class="title-icon unactive"
            :name="item.meta.icon"
          />
          <IkSvgIcon
            v-if="item.meta?.activeIcon || item.meta?.icon"
            :size="18"
            class="title-icon active"
            :name="(item.meta.activeIcon || item.meta.icon) as string"
          />
        </template>
        <span v-else class="sub-menu-point"></span>
        <!-- RM: 侧边栏一级导航 -->
        <span class="ik-menu-title">{{ generateI18nTitle(item.meta?.i18n, item.meta?.title) }}</span>
        <span
          v-if="badge(item.meta?.badge).visible"
          class="badge"
          :class="{
            'badge-dot': badge(item.meta?.badge).type === 'dot',
            'badge-text': badge(item.meta?.badge).type === 'text',
          }"
        >{{
          badge(item.meta?.badge).type === 'text'
            ? badge(item.meta?.badge).value
            : ''
        }}</span>
      </template>
      <template v-for="route in item.children">
        <SidebarItem
          v-if="route.meta?.sidebar !== false"
          :key="route.path"
          :item="route"
          :base-path="resolveRoutePath(basePath, item.path || item.meta?.path)"
        />
      </template>
    </el-sub-menu>
  </div>
</template>

<style lang="scss" scoped>
.sidebar-item {
  /* transition: padding 0.3s; */
  padding-bottom: 5px;
  padding-top: 5px;

  .sub-menu-point {
    display: inline-block;
    width: 4px;
    height: 4px;
    background-color: var(--ik-sub-sidebar-menu-color);
    border-radius: 50%;
    margin-right: 13px;
  }

  .el-menu-item.is-active .sub-menu-point {
    background-color: var(--ik-sub-sidebar-menu-active-color);
  }

  .el-menu-item:hover .sub-menu-point {
    background-color: var(--ik-sub-sidebar-menu-hover-color);
  }

  a {
    cursor: pointer;
    color: inherit;
    text-decoration: none;
  }

  .badge {
    position: absolute;
    z-index: 1;
    background-color: var(--ik-badge-bg);
    box-shadow: 0 0 0 1px var(--ik-badge-border-color);
    transition: background-color 0.3s, var(--el-transition-box-shadow);

    @include position-center(y);

    &-dot {
      right: 15px;
      border-radius: 50%;
      width: 6px;
      height: 6px;

      &::after {
        content: '';
        pointer-events: none;
        position: absolute;
        top: 0;
        display: block;
        width: 6px;
        height: 6px;
        border-radius: 50%;
        animation: dot-twinkling 1s infinite ease-in-out;
        background-color: var(--ik-badge-bg);
        transition: background-color 0.3s;
      }
    }

    @keyframes dot-twinkling {
      0% {
        opacity: 0.6;
        transform: scale(0.8);
      }

      100% {
        opacity: 0;
        transform: scale(2.4);
      }
    }

    &-text {
      right: 15px;
      border-radius: 10px;
      font-size: 12px;
      height: 18px;
      line-height: 18px;
      padding: 0 6px;
      text-align: center;
      white-space: nowrap;
      color: var(--ik-badge-color);
    }
  }

  .el-sub-menu__title {
    >.badge {
      &-dot {
        right: 40px;
      }

      &-text {
        right: 40px;
      }
    }
  }

  :deep(.el-menu-item),
  :deep(.el-menu-item span.ik-menu-title),
  :deep(.el-sub-menu__title),
  :deep(.el-sub-menu__title span.ik-menu-title) {
    flex: 1;
    vertical-align: inherit;
    user-select: none;

    @include text-overflow;
  }

  :deep(.el-menu-item) {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  :deep(.el-sub-menu),
  :deep(.el-menu-item) {
    &.none-body.single-menu{
      .el-sub-menu__icon-arrow {
        display: none;
      }
    }

    .title-icon {
      transition: transform 0.3s;

      /* color: unset; */
      padding: 0 !important;
    }

    .title-icon+.ik-menu-title {
      margin: 0 5px;
      height: 25px;
      line-height: 25px;
    }

    &:hover>.title-icon,
    .el-sub-menu__title:hover>.title-icon {
      transform: scale(1.1);
    }
  }

  :deep(.el-sub-menu) {
    >.el-sub-menu__title>.title-icon.active {
      display: none;
    }

    &.is-active {
      >.el-sub-menu__title>.title-icon.unactive {
        display: none;
      }

      >.el-sub-menu__title>.title-icon.active {
        display: flex;
      }
    }

    &.is-firstLevel .el-sub-menu__title {
      margin-left: calc(var(--el-menu-base-level-padding) + var(--el-menu-level) * var(--el-menu-level-padding));
      padding-left: 16px;
    }
  }
}
</style>

<style lang="scss">
.el-menu.el-menu--vertical.el-menu--collapse.fa-menu {
  .el-sub-menu.is-firstLevel .el-sub-menu__title {
    margin-left: 5px;
    padding-left: 16px;
  }
}
</style>
